home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-m68k / bitops.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  10.7 KB  |  460 lines

  1. #ifndef _M68K_BITOPS_H
  2. #define _M68K_BITOPS_H
  3. /*
  4.  * Copyright 1992, Linus Torvalds.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file COPYING in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. #ifndef _LINUX_BITOPS_H
  12. #error only <linux/bitops.h> can be included directly
  13. #endif
  14.  
  15. #include <linux/compiler.h>
  16.  
  17. /*
  18.  * Require 68020 or better.
  19.  *
  20.  * They use the standard big-endian m680x0 bit ordering.
  21.  */
  22.  
  23. #define test_and_set_bit(nr,vaddr) \
  24.   (__builtin_constant_p(nr) ? \
  25.    __constant_test_and_set_bit(nr, vaddr) : \
  26.    __generic_test_and_set_bit(nr, vaddr))
  27.  
  28. #define __test_and_set_bit(nr,vaddr) test_and_set_bit(nr,vaddr)
  29.  
  30. static inline int __constant_test_and_set_bit(int nr, unsigned long *vaddr)
  31. {
  32.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  33.     char retval;
  34.  
  35.     __asm__ __volatile__ ("bset %2,%1; sne %0"
  36.             : "=d" (retval), "+m" (*p)
  37.             : "di" (nr & 7));
  38.  
  39.     return retval;
  40. }
  41.  
  42. static inline int __generic_test_and_set_bit(int nr, unsigned long *vaddr)
  43. {
  44.     char retval;
  45.  
  46.     __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
  47.             : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory");
  48.  
  49.     return retval;
  50. }
  51.  
  52. #define set_bit(nr,vaddr) \
  53.   (__builtin_constant_p(nr) ? \
  54.    __constant_set_bit(nr, vaddr) : \
  55.    __generic_set_bit(nr, vaddr))
  56.  
  57. #define __set_bit(nr,vaddr) set_bit(nr,vaddr)
  58.  
  59. static inline void __constant_set_bit(int nr, volatile unsigned long *vaddr)
  60. {
  61.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  62.     __asm__ __volatile__ ("bset %1,%0"
  63.             : "+m" (*p) : "di" (nr & 7));
  64. }
  65.  
  66. static inline void __generic_set_bit(int nr, volatile unsigned long *vaddr)
  67. {
  68.     __asm__ __volatile__ ("bfset %1{%0:#1}"
  69.             : : "d" (nr^31), "o" (*vaddr) : "memory");
  70. }
  71.  
  72. #define test_and_clear_bit(nr,vaddr) \
  73.   (__builtin_constant_p(nr) ? \
  74.    __constant_test_and_clear_bit(nr, vaddr) : \
  75.    __generic_test_and_clear_bit(nr, vaddr))
  76.  
  77. #define __test_and_clear_bit(nr,vaddr) test_and_clear_bit(nr,vaddr)
  78.  
  79. static inline int __constant_test_and_clear_bit(int nr, unsigned long *vaddr)
  80. {
  81.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  82.     char retval;
  83.  
  84.     __asm__ __volatile__ ("bclr %2,%1; sne %0"
  85.             : "=d" (retval), "+m" (*p)
  86.             : "di" (nr & 7));
  87.  
  88.     return retval;
  89. }
  90.  
  91. static inline int __generic_test_and_clear_bit(int nr, unsigned long *vaddr)
  92. {
  93.     char retval;
  94.  
  95.     __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
  96.             : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory");
  97.  
  98.     return retval;
  99. }
  100.  
  101. /*
  102.  * clear_bit() doesn't provide any barrier for the compiler.
  103.  */
  104. #define smp_mb__before_clear_bit()    barrier()
  105. #define smp_mb__after_clear_bit()    barrier()
  106.  
  107. #define clear_bit(nr,vaddr) \
  108.   (__builtin_constant_p(nr) ? \
  109.    __constant_clear_bit(nr, vaddr) : \
  110.    __generic_clear_bit(nr, vaddr))
  111. #define __clear_bit(nr,vaddr) clear_bit(nr,vaddr)
  112.  
  113. static inline void __constant_clear_bit(int nr, volatile unsigned long *vaddr)
  114. {
  115.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  116.     __asm__ __volatile__ ("bclr %1,%0"
  117.             : "+m" (*p) : "di" (nr & 7));
  118. }
  119.  
  120. static inline void __generic_clear_bit(int nr, volatile unsigned long *vaddr)
  121. {
  122.     __asm__ __volatile__ ("bfclr %1{%0:#1}"
  123.             : : "d" (nr^31), "o" (*vaddr) : "memory");
  124. }
  125.  
  126. #define test_and_change_bit(nr,vaddr) \
  127.   (__builtin_constant_p(nr) ? \
  128.    __constant_test_and_change_bit(nr, vaddr) : \
  129.    __generic_test_and_change_bit(nr, vaddr))
  130.  
  131. #define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr)
  132. #define __change_bit(nr,vaddr) change_bit(nr,vaddr)
  133.  
  134. static inline int __constant_test_and_change_bit(int nr, unsigned long *vaddr)
  135. {
  136.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  137.     char retval;
  138.  
  139.     __asm__ __volatile__ ("bchg %2,%1; sne %0"
  140.             : "=d" (retval), "+m" (*p)
  141.             : "di" (nr & 7));
  142.  
  143.     return retval;
  144. }
  145.  
  146. static inline int __generic_test_and_change_bit(int nr, unsigned long *vaddr)
  147. {
  148.     char retval;
  149.  
  150.     __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0"
  151.             : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory");
  152.  
  153.     return retval;
  154. }
  155.  
  156. #define change_bit(nr,vaddr) \
  157.   (__builtin_constant_p(nr) ? \
  158.    __constant_change_bit(nr, vaddr) : \
  159.    __generic_change_bit(nr, vaddr))
  160.  
  161. static inline void __constant_change_bit(int nr, unsigned long *vaddr)
  162. {
  163.     char *p = (char *)vaddr + (nr ^ 31) / 8;
  164.     __asm__ __volatile__ ("bchg %1,%0"
  165.             : "+m" (*p) : "di" (nr & 7));
  166. }
  167.  
  168. static inline void __generic_change_bit(int nr, unsigned long *vaddr)
  169. {
  170.     __asm__ __volatile__ ("bfchg %1{%0:#1}"
  171.             : : "d" (nr^31), "o" (*vaddr) : "memory");
  172. }
  173.  
  174. static inline int test_bit(int nr, const unsigned long *vaddr)
  175. {
  176.     return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
  177. }
  178.  
  179. static inline int find_first_zero_bit(const unsigned long *vaddr,
  180.                       unsigned size)
  181. {
  182.     const unsigned long *p = vaddr;
  183.     int res = 32;
  184.     unsigned long num;
  185.  
  186.     if (!size)
  187.         return 0;
  188.  
  189.     size = (size + 31) >> 5;
  190.     while (!(num = ~*p++)) {
  191.         if (!--size)
  192.             goto out;
  193.     }
  194.  
  195.     __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  196.                   : "=d" (res) : "d" (num & -num));
  197.     res ^= 31;
  198. out:
  199.     return ((long)p - (long)vaddr - 4) * 8 + res;
  200. }
  201.  
  202. static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
  203.                      int offset)
  204. {
  205.     const unsigned long *p = vaddr + (offset >> 5);
  206.     int bit = offset & 31UL, res;
  207.  
  208.     if (offset >= size)
  209.         return size;
  210.  
  211.     if (bit) {
  212.         unsigned long num = ~*p++ & (~0UL << bit);
  213.         offset -= bit;
  214.  
  215.         /* Look for zero in first longword */
  216.         __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  217.                       : "=d" (res) : "d" (num & -num));
  218.         if (res < 32)
  219.             return offset + (res ^ 31);
  220.         offset += 32;
  221.     }
  222.     /* No zero yet, search remaining full bytes for a zero */
  223.     res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8);
  224.     return offset + res;
  225. }
  226.  
  227. static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
  228. {
  229.     const unsigned long *p = vaddr;
  230.     int res = 32;
  231.     unsigned long num;
  232.  
  233.     if (!size)
  234.         return 0;
  235.  
  236.     size = (size + 31) >> 5;
  237.     while (!(num = *p++)) {
  238.         if (!--size)
  239.             goto out;
  240.     }
  241.  
  242.     __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  243.                   : "=d" (res) : "d" (num & -num));
  244.     res ^= 31;
  245. out:
  246.     return ((long)p - (long)vaddr - 4) * 8 + res;
  247. }
  248.  
  249. static inline int find_next_bit(const unsigned long *vaddr, int size,
  250.                 int offset)
  251. {
  252.     const unsigned long *p = vaddr + (offset >> 5);
  253.     int bit = offset & 31UL, res;
  254.  
  255.     if (offset >= size)
  256.         return size;
  257.  
  258.     if (bit) {
  259.         unsigned long num = *p++ & (~0UL << bit);
  260.         offset -= bit;
  261.  
  262.         /* Look for one in first longword */
  263.         __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  264.                       : "=d" (res) : "d" (num & -num));
  265.         if (res < 32)
  266.             return offset + (res ^ 31);
  267.         offset += 32;
  268.     }
  269.     /* No one yet, search remaining full bytes for a one */
  270.     res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8);
  271.     return offset + res;
  272. }
  273.  
  274. /*
  275.  * ffz = Find First Zero in word. Undefined if no zero exists,
  276.  * so code should check against ~0UL first..
  277.  */
  278. static inline unsigned long ffz(unsigned long word)
  279. {
  280.     int res;
  281.  
  282.     __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  283.                   : "=d" (res) : "d" (~word & -~word));
  284.     return res ^ 31;
  285. }
  286.  
  287. #ifdef __KERNEL__
  288.  
  289. /*
  290.  * ffs: find first bit set. This is defined the same way as
  291.  * the libc and compiler builtin ffs routines, therefore
  292.  * differs in spirit from the above ffz (man ffs).
  293.  */
  294.  
  295. static inline int ffs(int x)
  296. {
  297.     int cnt;
  298.  
  299.     asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x));
  300.  
  301.     return 32 - cnt;
  302. }
  303. #define __ffs(x) (ffs(x) - 1)
  304.  
  305. /*
  306.  * fls: find last bit set.
  307.  */
  308.  
  309. static inline int fls(int x)
  310. {
  311.     int cnt;
  312.  
  313.     asm ("bfffo %1{#0,#0},%0" : "=d" (cnt) : "dm" (x));
  314.  
  315.     return 32 - cnt;
  316. }
  317.  
  318. #include <asm-generic/bitops/fls64.h>
  319. #include <asm-generic/bitops/sched.h>
  320. #include <asm-generic/bitops/hweight.h>
  321. #include <asm-generic/bitops/lock.h>
  322.  
  323. /* Bitmap functions for the minix filesystem */
  324.  
  325. static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size)
  326. {
  327.     const unsigned short *p = vaddr, *addr = vaddr;
  328.     int res;
  329.     unsigned short num;
  330.  
  331.     if (!size)
  332.         return 0;
  333.  
  334.     size = (size >> 4) + ((size & 15) > 0);
  335.     while (*p++ == 0xffff)
  336.     {
  337.         if (--size == 0)
  338.             return (p - addr) << 4;
  339.     }
  340.  
  341.     num = ~*--p;
  342.     __asm__ __volatile__ ("bfffo %1{#16,#16},%0"
  343.                   : "=d" (res) : "d" (num & -num));
  344.     return ((p - addr) << 4) + (res ^ 31);
  345. }
  346.  
  347. #define minix_test_and_set_bit(nr, addr)    __test_and_set_bit((nr) ^ 16, (unsigned long *)(addr))
  348. #define minix_set_bit(nr,addr)            __set_bit((nr) ^ 16, (unsigned long *)(addr))
  349. #define minix_test_and_clear_bit(nr, addr)    __test_and_clear_bit((nr) ^ 16, (unsigned long *)(addr))
  350.  
  351. static inline int minix_test_bit(int nr, const void *vaddr)
  352. {
  353.     const unsigned short *p = vaddr;
  354.     return (p[nr >> 4] & (1U << (nr & 15))) != 0;
  355. }
  356.  
  357. /* Bitmap functions for the ext2 filesystem. */
  358.  
  359. #define ext2_set_bit(nr, addr)            __test_and_set_bit((nr) ^ 24, (unsigned long *)(addr))
  360. #define ext2_set_bit_atomic(lock, nr, addr)    test_and_set_bit((nr) ^ 24, (unsigned long *)(addr))
  361. #define ext2_clear_bit(nr, addr)        __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
  362. #define ext2_clear_bit_atomic(lock, nr, addr)    test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
  363.  
  364. static inline int ext2_test_bit(int nr, const void *vaddr)
  365. {
  366.     const unsigned char *p = vaddr;
  367.     return (p[nr >> 3] & (1U << (nr & 7))) != 0;
  368. }
  369.  
  370. static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
  371. {
  372.     const unsigned long *p = vaddr, *addr = vaddr;
  373.     int res;
  374.  
  375.     if (!size)
  376.         return 0;
  377.  
  378.     size = (size >> 5) + ((size & 31) > 0);
  379.     while (*p++ == ~0UL)
  380.     {
  381.         if (--size == 0)
  382.             return (p - addr) << 5;
  383.     }
  384.  
  385.     --p;
  386.     for (res = 0; res < 32; res++)
  387.         if (!ext2_test_bit (res, p))
  388.             break;
  389.     return (p - addr) * 32 + res;
  390. }
  391.  
  392. static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
  393.                       unsigned offset)
  394. {
  395.     const unsigned long *addr = vaddr;
  396.     const unsigned long *p = addr + (offset >> 5);
  397.     int bit = offset & 31UL, res;
  398.  
  399.     if (offset >= size)
  400.         return size;
  401.  
  402.     if (bit) {
  403.         /* Look for zero in first longword */
  404.         for (res = bit; res < 32; res++)
  405.             if (!ext2_test_bit (res, p))
  406.                 return (p - addr) * 32 + res;
  407.         p++;
  408.     }
  409.     /* No zero yet, search remaining full bytes for a zero */
  410.     res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
  411.     return (p - addr) * 32 + res;
  412. }
  413.  
  414. static inline int ext2_find_first_bit(const void *vaddr, unsigned size)
  415. {
  416.     const unsigned long *p = vaddr, *addr = vaddr;
  417.     int res;
  418.  
  419.     if (!size)
  420.         return 0;
  421.  
  422.     size = (size >> 5) + ((size & 31) > 0);
  423.     while (*p++ == 0UL) {
  424.         if (--size == 0)
  425.             return (p - addr) << 5;
  426.     }
  427.  
  428.     --p;
  429.     for (res = 0; res < 32; res++)
  430.         if (ext2_test_bit(res, p))
  431.             break;
  432.     return (p - addr) * 32 + res;
  433. }
  434.  
  435. static inline int ext2_find_next_bit(const void *vaddr, unsigned size,
  436.                      unsigned offset)
  437. {
  438.     const unsigned long *addr = vaddr;
  439.     const unsigned long *p = addr + (offset >> 5);
  440.     int bit = offset & 31UL, res;
  441.  
  442.     if (offset >= size)
  443.         return size;
  444.  
  445.     if (bit) {
  446.         /* Look for one in first longword */
  447.         for (res = bit; res < 32; res++)
  448.             if (ext2_test_bit(res, p))
  449.                 return (p - addr) * 32 + res;
  450.         p++;
  451.     }
  452.     /* No set bit yet, search remaining full bytes for a set bit */
  453.     res = ext2_find_first_bit(p, size - 32 * (p - addr));
  454.     return (p - addr) * 32 + res;
  455. }
  456.  
  457. #endif /* __KERNEL__ */
  458.  
  459. #endif /* _M68K_BITOPS_H */
  460.